@file:Suppress("unused")

package com.hitcoder.chat.adapter

import android.graphics.Bitmap
import android.graphics.drawable.Drawable
import android.util.TypedValue
import android.view.LayoutInflater
import android.view.View
import android.view.View.OnLongClickListener
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView

class BaseViewHolder(parent: ViewGroup, resource: Int) : RecyclerView.ViewHolder(
    LayoutInflater.from(parent.context).inflate(resource, parent, false)
)

abstract class ViewHolderCreator<T> {
    abstract fun isForViewType(data: T?, position: Int): Boolean
    abstract fun getResourceId(): Int
    abstract fun onBindViewHolder(
        data: T?,
        items: MutableList<T>?,
        position: Int,
        holder: ViewHolderCreator<T>
    )

    lateinit var itemView: View

    fun registerItemView(itemView: View?) {
        if (itemView == null) {
            throw NullPointerException("itemView is null")
        }
        this.itemView = itemView
    }

    fun <V : View> findViewById(viewId: Int): V {
        return itemView.findViewById(viewId)
    }
}

fun <T> ViewHolderCreator<T>.setText(viewId: Int, text: String?) = apply {
    findViewById<TextView>(viewId).text = text
}

fun <T> ViewHolderCreator<T>.setImageResource(viewId: Int, resId: Int) = apply {
    findViewById<ImageView>(viewId).setImageResource(resId)
}

fun <T> ViewHolderCreator<T>.setImageBitmap(viewId: Int, bm: Bitmap?) = apply {
    findViewById<ImageView>(viewId).setImageBitmap(bm)
}

fun <T> ViewHolderCreator<T>.setImageDrawable(viewId: Int, drawable: Drawable?) = apply {
    findViewById<ImageView>(viewId).setImageDrawable(drawable)
}

fun <T> ViewHolderCreator<T>.setBackground(viewId: Int, drawable: Drawable?) = apply {
    findViewById<ImageView>(viewId).apply {
        background = drawable
    }
}

fun <T> ViewHolderCreator<T>.setBackgroundResource(viewId: Int, resid: Int) = apply {
    findViewById<ImageView>(viewId).setBackgroundResource(resid)
}

fun <T> ViewHolderCreator<T>.visible(id: Int) =
    apply { findViewById<View>(id).visibility = View.VISIBLE }

fun <T> ViewHolderCreator<T>.invisible(id: Int) =
    apply { findViewById<View>(id).visibility = View.INVISIBLE }

fun <T> ViewHolderCreator<T>.gone(id: Int) = apply { findViewById<View>(id).visibility = View.GONE }

fun <T> ViewHolderCreator<T>.visibility(id: Int, visibility: Int) =
    apply { findViewById<View>(id).visibility = visibility }

fun <T> ViewHolderCreator<T>.setTextColor(id: Int, color: Int) = apply {
    findViewById<TextView>(id).setTextColor(color)
}

fun <T> ViewHolderCreator<T>.setTextSize(id: Int, sp: Int) = apply {
    findViewById<TextView>(id).setTextSize(TypedValue.COMPLEX_UNIT_SP, sp.toFloat())
}

fun <T> ViewHolderCreator<T>.clicked(id: Int, listener: View.OnClickListener) =
    apply { findViewById<View>(id).setOnClickListener(listener) }

fun <T> ViewHolderCreator<T>.clicked(id: Int, listener: (View) -> Unit) =
    apply { findViewById<View>(id).setOnClickListener(listener) }

fun <T> ViewHolderCreator<T>.itemClicked(listener: View.OnClickListener) =
    apply { itemView.setOnClickListener(listener) }

fun <T> ViewHolderCreator<T>.itemClicked(listener: (View) -> Unit) =
    apply { itemView.setOnClickListener(listener) }

fun <T> ViewHolderCreator<T>.longClicked(id: Int, listener: OnLongClickListener) =
    apply { findViewById<View>(id).setOnLongClickListener(listener) }

fun <T> ViewHolderCreator<T>.longClicked(id: Int, listener: (View) -> Boolean) =
    apply { findViewById<View>(id).setOnLongClickListener(listener) }

fun <T> ViewHolderCreator<T>.setEnabled(id: Int, enable: Boolean = true) =
    apply { findViewById<View>(id).isEnabled = enable }

fun <T> ViewHolderCreator<T>.addView(id: Int, vararg views: View?) = apply {
    val viewGroup: ViewGroup = findViewById(id)
    for (view in views) {
        viewGroup.addView(view)
    }
}

fun <T> ViewHolderCreator<T>.addView(id: Int, view: View?, params: ViewGroup.LayoutParams?) =
    apply {
        val viewGroup: ViewGroup = findViewById(id)
        viewGroup.addView(view, params)
    }

fun <T> ViewHolderCreator<T>.removeAllViews(id: Int) = apply {
    val viewGroup: ViewGroup = findViewById(id)
    viewGroup.removeAllViews()
}

fun <T> ViewHolderCreator<T>.removeView(id: Int, view: View?) = apply {
    findViewById<ViewGroup>(id).removeView(view)
}
